﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using MyLibrary.ThreeLayer.DataAccess.Interface;

namespace MyLibrary.ThreeLayer.DataAccess.Provider.SQLParser.MSSQL
{
    internal abstract class SingleOperatorParser : IOperatorParser
    {
        protected SingleOperatorParser()
        {
        }

        protected string BuildUniqeName(string fieldName, int index)
        {
            return String.Concat(new object[] { "@", fieldName, "_", index });
        }

        protected abstract string GetOperator();

        public string Parser(string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            string key = this.BuildUniqeName(fieldName, index);
            paramList.Add(key, value);
            return ("[" + fieldName + "] " + this.GetOperator() + " " + key);
        }

        public string Parser(string tableName, string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            string key = this.BuildUniqeName(fieldName, index);
            paramList.Add(key, value);
            return ("[" + tableName + "].[" + fieldName + "] " + this.GetOperator() + " " + key);
        }
    }

    internal class BetweenParser : IOperatorParser
    {
        public string Parser(string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = new object[2];
            int num = 0;

            foreach (object obj in (IEnumerable)value)
            {
                objArray[num] = obj;
                num++;
            }

            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(fieldName)
                .Append("] Between")
                .Append("@")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_1");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_1" }), objArray[0]);

            builder.Append(" And @")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_2");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_2" }), objArray[1]);
            return builder.ToString();
        }

        public string Parser(string tableName, string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = new object[2];
            int num = 0;

            foreach (object obj in (IEnumerable)value)
            {
                objArray[num] = obj;
                num++;
            }

            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(tableName)
                .Append("].[")
                .Append(fieldName)
                .Append("] Between")
                .Append("@")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_1");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_1" }), objArray[0]);

            builder.Append(" And @")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_2");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_2" }), objArray[1]);
            return builder.ToString();
        }
    }

    internal class NotBetweenParser : IOperatorParser
    {
        public string Parser(string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = new object[2];
            int num = 0;

            foreach (object obj in (IEnumerable)value)
            {
                objArray[num] = obj;
                num++;
            }

            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(fieldName)
                .Append("] Not Between")
                .Append("@")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_1");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_1" }), objArray[0]);

            builder.Append(" And @")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_2");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_2" }), objArray[1]);
            return builder.ToString();
        }

        public string Parser(string tableName, string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = new object[2];
            int num = 0;

            foreach (object obj in (IEnumerable)value)
            {
                objArray[num] = obj;
                num++;
            }

            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(tableName)
                .Append("].[")
                .Append(fieldName)
                .Append("] Not Between")
                .Append("@")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_1");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_1" }), objArray[0]);

            builder.Append(" And @")
                .Append(fieldName)
                .Append("_")
                .Append(index.ToString())
                .Append("_2");
            paramList.Add(string.Concat(new object[] { "@", fieldName, "_", index, "_2" }), objArray[1]);
            return builder.ToString();
        }
    }

    internal class EqualParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return "=";
        }
    }

    internal class InParser : IOperatorParser
    {

        #region IOperatorParser Members

        public string Parser(string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = (object[]) value;
            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(fieldName)
                .Append("] In (");

            for (int i = 0; i < objArray.Length; i++)
            {
                if (i > 0)
                    builder.Append(",");
                builder.Append("'")
                    .Append(objArray[i].ToString())
                    .Append("'");
            }
            builder.Append(")");
            return builder.ToString();
        }

        public string Parser(string tableName, string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = (object[])value;
            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(tableName)
                .Append("].[")
                .Append(fieldName)
                .Append("] In (");

            for (int i = 0; i < objArray.Length; i++)
            {
                if (i > 0)
                    builder.Append(",");
                builder.Append("'")
                    .Append(objArray[i].ToString())
                    .Append("'");
            }
            builder.Append(")");
            return builder.ToString();
        }

        #endregion
    }

    internal class IsNotNullParser : IOperatorParser
    {

        #region IOperatorParser Members

        public string Parser(string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            return ("[" + fieldName + "] Is Not Null");
        }

        public string Parser(string tableName, string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            return ("[" + tableName + "].[" + fieldName + "] Is Not Null");
        }

        #endregion
    }

    internal class IsNullParser : IOperatorParser
    {

        #region IOperatorParser Members

        public string Parser(string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            return ("[" + fieldName + "] Is Null");
        }

        public string Parser(string tableName, string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            return ("[" + tableName + "].[" + fieldName + "] Is Null");
        }

        #endregion
    }

    internal class LessEqualParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return "<=";
        }
    }

    internal class LessThenParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return "<";
        }
    }

    internal class MoreEqualParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return ">=";
        }
    }

    internal class MoreThenParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return ">";
        }
    }

    internal class LikeParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return "Like";
        }
    }

    internal class NotLikeParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return "Not Like";
        }
    }

    internal class NotEqualParser : SingleOperatorParser
    {
        protected override string GetOperator()
        {
            return "<>";
        }
    }

    internal class NotInParser : IOperatorParser
    {

        #region IOperatorParser Members

        public string Parser(string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = (object[])value;
            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(fieldName)
                .Append("] Not In (");

            for (int i = 0; i < objArray.Length; i++)
            {
                if (i > 0)
                    builder.Append(",");
                builder.Append("'")
                    .Append(objArray[i].ToString())
                    .Append("'");
            }
            builder.Append(")");
            return builder.ToString();
        }

        public string Parser(string tableName, string fieldName, int index, object value, IDictionary<string, object> paramList)
        {
            object[] objArray = (object[])value;
            StringBuilder builder = new StringBuilder();
            builder.Append(" [")
                .Append(tableName)
                .Append("].[")
                .Append(fieldName)
                .Append("] Not In (");

            for (int i = 0; i < objArray.Length; i++)
            {
                if (i > 0)
                    builder.Append(",");
                builder.Append("'")
                    .Append(objArray[i].ToString())
                    .Append("'");
            }
            builder.Append(")");
            return builder.ToString();
        }

        #endregion
    }
}
